package com.Helper;

import java.sql.*;
import java.util.*;

import com.database.CustomerDB;
import com.database.FlightDB;
import com.database.ReservationDB;

public class FlightHelper 
{
	private static Connection connection = null;
	
	public static void Setup(Connection _connection) throws SQLException
	{
		connection = _connection;
	}
	
	public static ArrayList<FlightInfo> GetAllFlights() throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetAllFlights(null);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetAllFlights(String date) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetAllFlights(date);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetFlightsByLeavingFrom(String leaving) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetFlightByLeavingFrom(leaving, null);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetFlightsByLeavingFrom(String leaving, String date) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetFlightByLeavingFrom(leaving, date);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetFlightsByArrivingAt(String arriving) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetFlightByArrivingAt(arriving, null);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetFlightsByArrivingAt(String arriving, String date) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetFlightByArrivingAt(arriving, date);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetFlightsByLeavingArriving(String leaving, String arriving) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetFlightByLeavingArriving(leaving, arriving, null);
		
		return list;
	}
	
	public static ArrayList<FlightInfo> GetFlightsByLeavingArriving(String leaving, String arriving, String date) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		ArrayList<FlightInfo> list = db.GetFlightByLeavingArriving(leaving, arriving, date);
		
		return list;
	}
	
	public static FlightInfo GetSelectedFlights(String flightID) throws SQLException
	{		
		FlightDB db = new FlightDB();
		db.Setup(connection);
		FlightInfo info = db.GetSelectedFlight(flightID);
		return info;
	}
	
	public static ArrayList<ConnectInfo> GetConnectingFlight(String leaving, String arriving) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		
		ArrayList<FlightInfo> leavingList = db.GetLeavingFlight(leaving, null);
		ArrayList<FlightInfo> arrivingList = db.GetArrivingFlight(arriving, null);
		ArrayList<ConnectInfo> connectList = new ArrayList<ConnectInfo>();
		
		for (int i = 0; i < leavingList.size(); i++)
		{
			for (int j = 0; j < arrivingList.size(); j++)
			{
				FlightInfo leavingInfo = leavingList.get(i);
				FlightInfo arrivingInfo = arrivingList.get(j);
				
				if (IsLocationSame(leavingInfo, arrivingInfo) == true)
				{
					if (IsDateOk(leavingInfo, arrivingInfo) == true)
					{
						if (IsTimeOk(leavingInfo, arrivingInfo) == true)
						{
							ConnectInfo connectInfo = new ConnectInfo();
							connectInfo.leavingInfo = arrivingInfo;
							connectInfo.arrivingInfo = leavingInfo;
							connectList.add(connectInfo);
						}
					}
				}
			}
		}
		
		return connectList;
	}
	
	public static ArrayList<ConnectInfo> GetConnectingFlight(String leaving, String arriving, String date) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		
		ArrayList<FlightInfo> leavingList = db.GetLeavingFlight(leaving, date);
		ArrayList<FlightInfo> arrivingList = db.GetArrivingFlight(arriving, date);
		ArrayList<ConnectInfo> connectList = new ArrayList<ConnectInfo>();
		
		for (int i = 0; i < leavingList.size(); i++)
		{
			for (int j = 0; j < arrivingList.size(); j++)
			{
				FlightInfo leavingInfo = leavingList.get(i);
				FlightInfo arrivingInfo = arrivingList.get(j);
				
				if (IsLocationSame(leavingInfo, arrivingInfo) == true)
				{
					if (IsDateOk(leavingInfo, arrivingInfo) == true)
					{
						if (IsTimeOk(leavingInfo, arrivingInfo) == true)
						{
							ConnectInfo connectInfo = new ConnectInfo();
							connectInfo.leavingInfo = arrivingInfo;
							connectInfo.arrivingInfo = leavingInfo;
							connectList.add(connectInfo);
						}
					}
				}
			}
		}
		
		return connectList;
	}
	
	public static boolean IsFull(String flightID) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		
		return db.IsFull(flightID);
	}
	
	public static boolean IsLocationSame(FlightInfo leaving, FlightInfo arriving)
	{
		// Arrival Location
		String arrival = leaving.arrivalLocation;
		
		// Departing Location
		String departing = arriving.departureLocation;
		
		if (arrival.equals(departing))
		{
			return true;
		}
		else 
		{
			return false;
		}
	}
	
	public static boolean IsTimeOk(FlightInfo leaving, FlightInfo arriving)
	{
		// Arrive at edmonton at 11am
		String arrivalTime = leaving.arrivalTime;
		// Leave edmonton at 11am
		String leavingTime = arriving.departureTime;
		
		int arrivalHour = Integer.parseInt(arrivalTime.substring(11, 13));
		int leavingHour = Integer.parseInt(leavingTime.substring(11, 13));
		
		if (arrivalHour < leavingHour)
		{
			return true;
		}
		else
		{
			return false;
		}		
	}
	
	public static boolean IsDateOk(FlightInfo leaving, FlightInfo arriving)
	{
		// Arrive at edmonton at 11am
		String arrivalTime = leaving.arrivalTime;
		
		// Leave edmonton at 11am
		String leavingTime = arriving.departureTime;
		
		int arrivalMonth = Integer.parseInt(arrivalTime.substring(5, 7));
		int leavingMonth = Integer.parseInt(leavingTime.substring(5, 7));
		
		if (arrivalMonth <= leavingMonth)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public static ArrayList<DestInfo> GetDestStats() throws SQLException
	{
		FlightDB flightDB = new FlightDB();
		flightDB.Setup(connection);
		ReservationDB resDB = new ReservationDB();
		resDB.Setup(connection);
		
		ArrayList<DestInfo> destList = flightDB.GetDestList();
		ArrayList<DestInfo> sortedList = new ArrayList<DestInfo>();
		ArrayList<ReservationInfo> resList = resDB.GetAllReservationInfo();
		int totalsize = destList.size();
		
		for (int i = 0; i < resList.size(); i++)
		{
			for (int j = 0; j < destList.size(); j++)
			{
				FlightInfo info = flightDB.GetSelectedFlight(resList.get(i).flightID);
				String dest = info.arrivalLocation;
				if (destList.get(j).arrivalLocation.equals(dest))
				{
					destList.get(j).count++;
				}
			}
		}
						
		for (int j = 0; j < totalsize; j++)
		{
			int max = 0;
			int index = 0;
			String location = null;
			for (int i = 0; i < destList.size(); i++)
			{
				DestInfo info = destList.get(i);
				if (info.count >= max)
				{
					max = info.count;
					index = i;
					location = info.arrivalLocation;
				}
			}
			DestInfo info = new DestInfo(location, max);
			sortedList.add(info);
			destList.remove(index);
		}
		
		for (int i = 0; i < sortedList.size(); i++)
		{
			System.out.println(sortedList.get(i).arrivalLocation + " " + sortedList.get(i).count);
		}
		
		return sortedList;
	}
	
	public static void MarkArrived(String flightID) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		db.MarkArrived(flightID);
		System.out.println(flightID + " has arrived.");
	}
	public static void MarkOnTime(String flightID) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		db.MarkOnTime(flightID);
		System.out.println(flightID + " is on time.");
	}
	
	public static void ModCapacity(String flightID, String option) throws SQLException
	{
		FlightDB db = new FlightDB();
		db.Setup(connection);
		FlightInfo info = db.GetSelectedFlight(flightID);
		
		if(option.equals("increase")){
			db.ModCapacity(++info.capacity, flightID);
		}else{
			db.ModCapacity(--info.capacity, flightID);
		}
	}
}
